package com.sq.partner.manager.service.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;

import com.sq.partner.manager.common.ActirationErrorInfo;
import com.sq.partner.manager.common.Config;
import com.sq.partner.manager.common.Constants;
import com.sq.partner.manager.common.DictCache;
import com.sq.partner.manager.common.Result;
import com.sq.partner.manager.common.exception.AppException;
import com.sq.partner.manager.dao.CommamtFeeDao;
import com.sq.partner.manager.dao.IGatewayAgentInfoMtDao;
import com.sq.partner.manager.dao.IGatewayAgentInfoRelaDao;
import com.sq.partner.manager.dao.INlifeCoreProdDao;
import com.sq.partner.manager.dao.INlifePlanDao;
import com.sq.partner.manager.dao.INlifeProdDao;
import com.sq.partner.manager.dao.OutboundCardApplyDao;
import com.sq.partner.manager.mybatis.model.CommamtFee;
import com.sq.partner.manager.mybatis.model.DictDto;
import com.sq.partner.manager.mybatis.model.FacadePayment;
import com.sq.partner.manager.mybatis.model.GatewayUser;
import com.sq.partner.manager.mybatis.model.NlifeCoreProd;
import com.sq.partner.manager.mybatis.model.NlifePlan;
import com.sq.partner.manager.mybatis.model.NlifeProd;
import com.sq.partner.manager.mybatis.model.OutboundCardApply;
import com.sq.partner.manager.mybatis.model.OutboundCardPrint;
import com.sq.partner.manager.service.OutboundCardApplyService;
import com.sq.partner.manager.util.DateUtil;
import com.sq.partner.manager.util.DecimalUtil;
import com.sq.partner.manager.util.LogUtil;
import com.sq.partner.manager.util.Page;
import com.sq.partner.manager.util.StrUtil;
import com.sq.partner.manager.util.WebServiceUtil;

@Service
public class OutboundCardApplyServiceImpl implements OutboundCardApplyService {
    private static Logger logger = LogUtil
            .getLog(OutboundCardApplyServiceImpl.class);

    @Resource
    private OutboundCardApplyDao outboundCardApplyDao;

    @Resource
    private IGatewayAgentInfoMtDao agentInfoMtDao;

    @Resource
    private INlifePlanDao nlifePlanDao;

    @Resource
    private IGatewayAgentInfoRelaDao tradAgentInfoRelaDao;

    @Resource
    private CommamtFeeDao commamtFeeDao;
    
    @Resource
    private INlifeProdDao nlifeProdDao;

    @Resource
    private INlifeCoreProdDao nlifeCoreProdDao;

    /**
     * 查询多条出库申请信息 根据条件 带分页
     * 
     * @return
     * @throws Exception
     */
    @Override
    public Page<OutboundCardApply> queryOutboundList(
            Page<OutboundCardApply> page) throws Exception {
        page = outboundCardApplyDao.queryOutboundList(page);

        return page;
    }

    @Override
    public Page<OutboundCardApply> queryCardInfoByCommamtId(
            Page<OutboundCardApply> page) throws Exception {

        page = outboundCardApplyDao.queryCardInfoByCommamtId(page);

        return page;
    }

    /**
     * 查询出单页面的卡单信息 根据条件 带分页
     * 
     * @return
     * @throws Exception
     */
    @Override
    public Page<OutboundCardApply> outboundAppliedList(
            Page<OutboundCardApply> page) throws Exception {
        // 查询出单页面的卡单信息列表
        page = outboundCardApplyDao.queryOutboundAppliedList(page);
        return page;

    }

    // /**
    // * 查询投保方案信息
    // * @return
    // * @throws Exception
    // */
    // @Override
    // public Result queryCardPlanList(String name, String channelCode) throws
    // Exception {
    // List<NlifePlan> nlifePlanList = null;
    // nlifePlanList=nlifePlanDao.queryPlanList(name, channelCode);
    // if(nlifePlanList==null || nlifePlanList.size()==0){
    // return Result.error("请先为该激活卡配置投保方案！");
    // }
    // //判断此种卡是否已经关联方案
    // String planNo = outboundCardApplyDao.queryPlanNo(name);
    // if(StrUtil.isEmpty(planNo)){
    // return Result.success(nlifePlanList);
    // }else{
    // return Result.success(planNo,nlifePlanList);
    // }
    // }

    /**
     * 查询投保方案信息
     * 
     * @return
     * @throws Exception
     */
    @Override
    public Map<String,Object> queryCardPlan(String planNo) throws Exception {
        Map<String,Object> map = new HashMap<String, Object>();
        NlifePlan plan = nlifePlanDao.queryById(planNo);
        NlifeProd nlifeProd = nlifeProdDao.queryProdInfoById(plan.getProdCode());
        NlifeCoreProd nlifeCoreProd = nlifeCoreProdDao.queryById(nlifeProd.getCoreProdCode());
        map.put("plan", plan);
        map.put("nlifeProd", nlifeProd);
        map.put("nlifeCoreProd", nlifeCoreProd);
        return map;
    }

    /**
     * 加载此出单机构下业务员信息
     * 
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, Object>> loadSalesMenData(String deptNo,
            String planNo, String partnerNo) throws Exception {
        List<Map<String, Object>> tradAgentList = null;
        tradAgentList = tradAgentInfoRelaDao.queryAgentInfoList(deptNo, planNo,
                partnerNo);
        return tradAgentList;
    }

    @Override
    public Result saveAgentRelaCardInfo(String name, String cardNo,
            String status, String count, String deptNo, String planNo,
            CommamtFee commamtFee) throws Exception {
        // //更新定义表里的方案号
        // boolean flag = outboundCardApplyDao.updatePlanNo(name,planNo);
        // if(!flag){
        // return Result.error(ActirationErrorInfo.OUT_3);
        // }

        Long start = System.currentTimeMillis();
        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("cardDefineId", commamtFee.getCardDefineId());
        paramMap.put("cardNo", cardNo);
        paramMap.put("status", status);
        paramMap.put("count", count);
        paramMap.put("deptNo", deptNo);
        // 防止脏数据
        List<OutboundCardApply> list = outboundCardApplyDao
                .queryUpdateList(paramMap);
        if (list != null && list.size() != Integer.parseInt(count)) {
            return Result.error("卡单表状态已更新，请重新查询！");
        }
        // 出库费用表新增出库记录
        String commamtId = null;
        commamtId = getCommamtId(Constants.COMMAMT_FEE);
        commamtFee.setCommamtId(commamtId);
        if ("Y".equals(commamtFee.getIsPreFee())) {
            commamtFee.setStatus(Constants.ACTIR_CARD_OUTBOUND_NOPAY);
        } else if ("N".equals(commamtFee.getIsPreFee())) {
            commamtFee.setStatus(Constants.ACTIR_CARD_OUTBOUND_PAY);
        }
        commamtFee.setBackPayFlag("0");
        boolean flag = commamtFeeDao.insertCommamtInfo(commamtFee);
        if (!flag) {
            return Result.error(ActirationErrorInfo.OUT_4);
        }
        // 出库ID关联到卡单主表
        paramMap.put("commamtId", commamtId);
        if ("Y".equals(commamtFee.getIsPreFee())) {
            paramMap.put("aftStatus", Constants.ACTIR_CARD_RELATION);
            paramMap.put("payMrk", Constants.PAY_MARK_N);
        } else {
            paramMap.put("aftStatus", Constants.ACTIR_CARD_ACTIVABLE);
            paramMap.put("payMrk", "");
        }
        paramMap.put("operatorNo", commamtFee.getOperatorNo() == null ? ""
                : commamtFee.getOperatorNo());
        paramMap.put("agentNo", commamtFee.getAgentNo() == null ? ""
                : commamtFee.getAgentNo());
        paramMap.put("discount", commamtFee.getAgentFee());
        paramMap.put(
                "agentProtocolNo",
                commamtFee.getAgentProtocolNo() == null ? "" : commamtFee
                        .getAgentProtocolNo());
        paramMap.put("premRate", commamtFee.getAgentPremRate());
        paramMap.put("cbrkrNme", commamtFee.getAgentMan() == null ? ""
                : commamtFee.getAgentMan());
        paramMap.put("empName",commamtFee.getOperatorName());
        paramMap.put("teamCode",commamtFee.getTeamCode());
        paramMap.put("teamName",commamtFee.getTeamName());
        paramMap.put("serviceCode",commamtFee.getCserviceCode());
        paramMap.put("serviceName",commamtFee.getCserviceName());
        paramMap.put("categoryCode",commamtFee.getBsnsType());
        paramMap.put("newBsnsType",commamtFee.getCchaLevel());
        paramMap.put("channleType",commamtFee.getCchannleType());
        paramMap.put("channleCode",commamtFee.getCchannleCode());
        flag = outboundCardApplyDao.updateStatusAndCommamtId(paramMap);
        logger.info("出库申请耗时 ： " + (System.currentTimeMillis() - start));
        if (!flag) {
            return Result.error(ActirationErrorInfo.OUT_5);
        }

        return Result.success(ActirationErrorInfo.OUT_6);
    }

    @Override
    public Result queryCountMax(HashMap<String, Object> map) throws Exception {
        Integer count = outboundCardApplyDao.queryCountMax(map);
        return Result.success(count);
    }

    // private String queryCommamtId() throws Exception{
    // String commamtId=null;
    // DataSource ds = (DataSource)ApplicationContextUtil.getBean("dataSource");
    // if(ds == null){
    // throw new AppException("无法获取数据源:"+ ds);
    // }
    // Connection conn = null;
    // PreparedStatement pstmt = null;
    // ResultSet rs = null;
    // String sql = "select SEQ_COMMAMT_FEE.nextval from dual ";
    // try{
    // conn = ds.getConnection();
    // pstmt = conn.prepareStatement(sql);
    // rs = pstmt.executeQuery();
    // while (rs.next()){
    // commamtId=rs.getString("nextval");
    // }
    // }finally{
    // BaseDaoImpl.close(rs);
    // BaseDaoImpl.close(pstmt);
    // BaseDaoImpl.close(conn);
    // }
    // return commamtId;
    // }
    private String getCommamtId(String table) {
        StringBuffer s = new StringBuffer();
        synchronized ("zz") {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            s.append(calendar.get(Calendar.YEAR));
            int month = calendar.get(Calendar.MONTH) + 1;
            if (month < 10) {
                s.append("0" + month);
            } else {
                s.append(month);
            }
            int day = calendar.get(Calendar.DATE);
            if (day < 10) {
                s.append("0" + day);
            } else {
                s.append(day);
            }
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            if (hour < 10) {
                s.append("0" + hour);
            } else {
                s.append(hour);
            }
            int min = calendar.get(Calendar.MINUTE);
            if (min < 10) {
                s.append("0" + min);
            } else {
                s.append(min);
            }
            int sec = calendar.get(Calendar.SECOND);
            if (sec < 10) {
                s.append("0" + sec);
            } else {
                s.append(sec);
            }
        }
        return table + s.toString()+"HZHB";
    }

    /**
     * 查询申请出库记录 根据条件 带分页
     * 
     * @return
     * @throws Exception
     */
    @Override
    public Page<CommamtFee> queryCommamtFeeList(Page<CommamtFee> page)
            throws Exception {
        page = commamtFeeDao.queryCommamtFeeList(page);

        return page;
    }

    /**
     * 缴费确认
     * 
     * @param commamtId
     * @param isPay
     * @return
     * @throws Exception
     */
    @Override
    public Result doConfirm(String commamtId, String isPay) throws Exception {
        HashMap<String, Object> param = new HashMap<String, Object>();
        param.put("commamtId", commamtId);
        param.put("statusBef", isPay);
        param.put("statusAft", Constants.ACTIR_CARD_OUTBOUND_PAY);
        // 更新出库费用表的状态和预收单号
        boolean flag = commamtFeeDao.updatCommamtInfo(param);
        if (!flag) {
            return Result.error("更新出库费用表失败！");
        }
        param.put("statusBef", Constants.ACTIR_CARD_RELATION);
        param.put("statusAft", Constants.ACTIR_CARD_ACTIVABLE);
        param.put("payMrk", "Y");
        flag = outboundCardApplyDao.updateStatusByCommamtId(param);
        if (!flag) {
            return Result.error("更新卡单主表失败！");
        }

        return Result.success("缴费确认成功！");
    }

    /**
     * 撤销出库
     * 
     * @param commamtId
     * @param isPay
     * @return
     * @throws Exception
     */
    @Override
    public Result doCancel(String commamtId, String isPay)
            throws Exception {
        HashMap<String, Object> param = new HashMap<String, Object>();
        param.put("commamtId", commamtId);
        param.put("statusBef", isPay);
        param.put("statusAft", Constants.ACTIR_CARD_OUTBOUND_CANCLE);
        // 更新出库费用表的状态(出库取消)
        boolean flag = commamtFeeDao.updatCommamtInfo(param);
        if (!flag) {
            return Result.error("更新出库费用表失败！");
        }
        param.put("statusBef", Constants.ACTIR_CARD_RELATION);
        param.put("statusAft", Constants.ACTIR_CARD_STOCK);
        param.put("operatorNo", null);
        param.put("agentNo", null);
        param.put("discount", null);
        param.put("premRate", null);
        param.put("agentProtocolNo", null);
        param.put("commamtIdAft", null);
        param.put("payMrk", null);
        param.put("cbrkrNme", null);
        param.put("empName",null);
        param.put("teamCode",null);
        param.put("teamName",null);
        param.put("serviceCode",null);
        param.put("serviceName",null);
        param.put("categoryCode",null);
        param.put("newBsnsType",null);
        param.put("channleType",null);
        param.put("channleCode",null);
        flag = outboundCardApplyDao.updateCancelStatusByCommamtId(param);
        if (!flag) {
            return Result.error("更新卡单主表失败！");
        }

        return Result.success("撤销出库成功！");
    }

    /**
     * 取得打印内容
     * 
     * @param commamtId
     * @return
     * @throws Exception
     */
    @Override
    public Result queryPremamtAndAgentFee(GatewayUser gatewayuser,
            String commamtId) throws Exception {
        CommamtFee daoFee = commamtFeeDao.getCommamtInfoByCommamtId(commamtId);
        if (daoFee == null) {
            return Result.error("没有此单出库记录！");
        } else {
            String printDate = DateUtil.format(new Date(), "yyyy-MM-dd");
            daoFee.setPrintDate(printDate);
            daoFee.setOperator(gatewayuser.getUserName() + "("
                    + gatewayuser.getUserCode() + ")");
        }
        List<String> cardNos = outboundCardApplyDao.getCardNoList(commamtId);
        if (cardNos == null || cardNos.size() == 0) {
            return Result.success(daoFee);
        }
        List<OutboundCardPrint> intervalCardNoList = getInterval(cardNos,
                daoFee.getAgentFee(), daoFee.getModalPremAmt(),
                daoFee.getName());
        daoFee.setCardNoList(intervalCardNoList);
        return Result.success(daoFee);
    }

    private List<OutboundCardPrint> getInterval(List<String> cardNos,
            BigDecimal agentFee, BigDecimal premAmt, String name) {
        List<OutboundCardPrint> cardList = new ArrayList<OutboundCardPrint>();
        OutboundCardPrint print = null;
        DecimalFormat df = new DecimalFormat(",##0.00");
        int tempCount = 1;
        String cardNoText = "";
        String cardStartNo = cardNos.get(0); // 卡段起始号
        String cardEndNo = cardNos.get(cardNos.size() - 1); // 卡段终止号

        // 只有一条卡号
        if (cardStartNo.equals(cardEndNo)) {

            print = new OutboundCardPrint();
            print.setCardNo(cardStartNo);
            print.setName(name);
            print.setHandleTotal(tempCount);
            print.setAgentFee(df.format(agentFee));
            print.setModalPremAmt(df.format(premAmt));
            print.setTotAgentFee(df.format(agentFee.multiply(new BigDecimal(
                    tempCount))));
            print.setTotPremAMt(df.format(premAmt.multiply(new BigDecimal(
                    tempCount))));

            cardList.add(print);
        } else {
            int length = cardNos.size();
            BigDecimal start = new BigDecimal(cardStartNo);
            BigDecimal end = new BigDecimal(cardEndNo);
            int d = end.subtract(start).intValue() + 1;
            // 全连续
            if (d == length) {
                cardNoText = cardStartNo + "到" + cardEndNo;
                print = new OutboundCardPrint();
                print.setCardNo(cardNoText);
                print.setName(name);
                print.setHandleTotal(length);
                print.setAgentFee(df.format(agentFee));
                print.setModalPremAmt(df.format(premAmt));
                print.setTotAgentFee(df.format(agentFee
                        .multiply(new BigDecimal(length))));
                print.setTotPremAMt(df.format(premAmt.multiply(new BigDecimal(
                        length))));

                cardList.add(print);
            } else {
                // 判断数组元数是否是公差为1的等差数列，元数之间是等差数列的就形成一条数据
                // 2条以上
                String currNo = "";
                String nextNo = "";
                String tempNo = cardStartNo;
                for (int i = 0; i < length; i++) {
                    print = new OutboundCardPrint();
                    currNo = cardNos.get(i);
                    nextNo = cardNos.get(length - 1);
                    if ((i + 1) < length) {
                        nextNo = cardNos.get(i + 1);
                    }

                    BigDecimal a1 = new BigDecimal(currNo);
                    BigDecimal a2 = new BigDecimal(nextNo);

                    int dd = a2.subtract(a1).intValue(); // 取公差

                    if (dd == 1 && nextNo.equals(cardEndNo)) {
                        if (currNo.equals(cardEndNo)) { // 只有一个
                            cardNoText = cardEndNo;
                        } else {
                            cardNoText = tempNo + "到" + cardEndNo;
                        }
                        tempCount = new BigDecimal(cardEndNo).subtract(
                                new BigDecimal(tempNo)).intValue() + 1; // 连续的卡单数
                        print.setCardNo(cardNoText);
                        print.setName(name);
                        print.setHandleTotal(tempCount);
                        print.setAgentFee(df.format(agentFee));
                        print.setModalPremAmt(df.format(premAmt));
                        print.setTotAgentFee(df.format(agentFee
                                .multiply(new BigDecimal(tempCount))));
                        print.setTotPremAMt(df.format(premAmt
                                .multiply(new BigDecimal(tempCount))));

                        cardList.add(print);
                        break;
                    } else if (dd != 1 && !nextNo.equals(cardEndNo)) {
                        if (currNo.equals(tempNo)) {
                            cardNoText = tempNo;
                        } else {
                            cardNoText = tempNo + "到" + currNo;
                        }
                        tempCount = new BigDecimal(currNo).subtract(
                                new BigDecimal(tempNo)).intValue() + 1; // 连续的卡单数
                        print.setCardNo(cardNoText);
                        print.setName(name);
                        print.setHandleTotal(tempCount);
                        print.setAgentFee(df.format(agentFee));
                        print.setModalPremAmt(df.format(premAmt));
                        print.setTotAgentFee(df.format(agentFee
                                .multiply(new BigDecimal(tempCount))));
                        print.setTotPremAMt(df.format(premAmt
                                .multiply(new BigDecimal(tempCount))));

                        cardList.add(print);
                        tempNo = nextNo;
                    } else if (dd != 1 && nextNo.equals(cardEndNo)) {
                        if (currNo.equals(tempNo)) {
                            cardNoText = tempNo;
                        } else {
                            cardNoText = tempNo + "到" + currNo;
                        }
                        tempCount = new BigDecimal(currNo).subtract(
                                new BigDecimal(tempNo)).intValue() + 1; // 连续的卡单数
                        print.setCardNo(cardNoText);
                        print.setName(name);
                        print.setHandleTotal(tempCount);
                        print.setAgentFee(df.format(agentFee));
                        print.setModalPremAmt(df.format(premAmt));
                        print.setTotAgentFee(df.format(agentFee
                                .multiply(new BigDecimal(tempCount))));
                        print.setTotPremAMt(df.format(premAmt
                                .multiply(new BigDecimal(tempCount))));

                        cardList.add(print);
                        tempNo = nextNo;
                    }
                }
            }
        }
        return cardList;
    }


	@Override
	public CommamtFee queryForPay(String commamtId)
			throws Exception {
		
		return commamtFeeDao.queryForPay(commamtId);
	}
    


    /**
     * 关联销售信息页面跳转前 往modelMap中存放字典表数据
     * 
     * @param modelMap
     * @throws Exception
     */
    @Override
    public void loadDictData(ModelMap modelMap) throws Exception {
        // 原业务来源
        List<DictDto> oldBSList = DictCache
                .getDict(Constants.DICT_OLD_BUSINESS_SOURCE);
//        // 新业务来源
//        List<DictDto> newBSList = DictCache
//                .getDict(Constants.DICT_NEW_BUSINESS_SOURCE);
        // 归属渠道
        List<DictDto> belongToChannelList = DictCache
                .getDict(Constants.DICT_BELONG_TO_CHANNEL);
//        // 渠道类型
//        List<DictDto> channelTypeList = DictCache
//                .getDict(Constants.DICT_CHANNEL_TYPE);
        modelMap.put("oldBSList", oldBSList);
//        modelMap.put("newBSList", newBSList);
        ObjectMapper mapper = new ObjectMapper();
        modelMap.put("belongToChannelList", mapper.writeValueAsString(
                belongToChannelList));
//        modelMap.put("channelTypeList", channelTypeList);
    }

    /**
     * 归属渠道-渠道类型-新业务来源处理(根据codeType和上级code从数据字典中查询下级级联信息)
     * 
     * @param dict
     * @return
     * @throws Exception
     */
    @Override
    public List<DictDto> loadSubCascadeList(DictDto dict) throws Exception {
        String codeType = dict.getCodeType();
        String parentCode = dict.getParentCode();

        List<DictDto> list = new ArrayList<DictDto>();
        if (StrUtil.isNotEmpty(codeType) && StrUtil.isNotEmpty(parentCode)) {
            List<DictDto> subDataList = DictCache.getDictDataByParentCode(
                    codeType, parentCode);
            // 复制list
            list.addAll(subDataList);
            // 倒序
            Collections.reverse(list);
            DictDto dd = new DictDto();
            dd.setCode("");
            dd.setCodeName("----请选择----");
            list.add(dd);
            // 倒序
            Collections.reverse(list);
            return list;
        } else {
            DictDto dd = new DictDto();
            dd.setCode("");
            if (Constants.DICT_CHANNEL_TYPE.equals(codeType)) {
                dd.setCodeName("----请选择归属渠道----");
            } else if (Constants.DICT_NEW_BUSINESS_SOURCE.equals(codeType)) {
                dd.setCodeName("----请选择渠道类型----");
            }
            list.add(dd);
        }
        return list;
    }

    /**
     * 根据归属机构代码(即出单机构)获取业务员List及团队List
     * 
     * @param deptNo
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    @Override
    public Result querySauserAndTeamInfo(String deptNo) throws Exception {
        String url = Config.getProp("SALES_WEBSERVICE_URL");
        String method = Config.getProp("querySauserAndTeamInfo_METHOD");
        String namespace = Config.getProp("querySauserAndTeamInfo_NAMESPACE");

        // 拼接请求报文
        String reqXml = "<?xml version=\"1.0\" encoding=\"GBK\"?>" + "<XML>"
                + "<USER>" +
                // 归属机构代码(必传)
                "<COMCODE>" + deptNo + "</COMCODE>" +
                // 业务员名称
                "<USERNAME></USERNAME>" +
                // 业务员代码(校验使用)
                "<USERCODE></USERCODE>" +
                // 渠道名称
                "<CHANNELNAME></CHANNELNAME>" +
                // 中介代码
                "<AGENTCODE></AGENTCODE>" + "</USER>" + "</XML>";
        logger.info("查询业务员-团队信息--》请求报文:" + reqXml);

        String respXml = "";
        try {
            // 调用销管接口
            respXml = WebServiceUtil.call(reqXml, url, method, namespace);
            logger.info("查询业务员-团队信息--》返回报文:" + respXml);
        } catch (Exception e) {
            logger.info("调用销管接口获取数据异常:", e);
            throw new AppException("调用销管接口获取数据异常:", e);
        }

        // 解析响应报文
        Document document = null;
        try {
            document = DocumentHelper.parseText(respXml);
        } catch (DocumentException e) {
            logger.info("解析销管返回报文异常", e);
            throw new AppException("解析销管返回报文异常:", e);
        }
        Element root = document.getRootElement();
        Element RETURN = root.element("RETURN");
        String RETURNCODE = RETURN.elementTextTrim("RETURNCODE");
        Element RETURNMSG = RETURN.element("RETURNMSG");
        
        String userCode = "";
        String userName = "";
        String channelName = "";
        String teamCode = "";
        String teamName = "";

        // 存放业务员和团队信息的List
        List<Map<String, Object>> TEAMUSERList = new ArrayList<Map<String, Object>>();
        if ("0000".equals(RETURNCODE)) {// 成功
            List<Element> TEAMUSER_elementList = RETURNMSG
                    .elements("TEAM-USER");
            for (Element TEAMUSER_element : TEAMUSER_elementList) {
                userCode = TEAMUSER_element.elementTextTrim("USERCODE");
                userName = TEAMUSER_element.elementTextTrim("USERNAME");

                Map<String, Object> TEAMUSER = new HashMap<String, Object>();
                TEAMUSER.put("USERCODE", userCode);// 业务员代码
                TEAMUSER.put("USERNAME", userName);// 业务员名称

                List<Element> TEAM_elementList = TEAMUSER_element
                        .elements("TEAM");
                // 存放每个业务员对应团队信息的List
                List<Map<String, String>> TEAMList = new ArrayList<Map<String, String>>();
                for (Element TEAM_element : TEAM_elementList) {
                    teamCode = TEAM_element.elementTextTrim("TEAMCODE");
                    teamName = TEAM_element.elementTextTrim("TEAMNAME");
                    channelName = TEAM_element.elementTextTrim("CHANNELNAME");

                    Map<String, String> TEAM = new HashMap<String, String>();
                    TEAM.put("TEAMCODE", teamCode);// 团队代码
                    TEAM.put("TEAMNAME", teamName);// 团队名称
                    TEAM.put("CHANNELNAME", channelName);// 渠道名称

                    TEAMList.add(TEAM);
                }
                TEAMUSER.put("TEAMList", TEAMList);
                TEAMUSERList.add(TEAMUSER);
            }

        } else {
            throw new AppException("调用销管接口获取数据失败:RETURNCODE:" + RETURNCODE
                    + "，RETURNMSG:" + RETURNMSG.getTextTrim());
        }
        return Result.success(TEAMUSERList);
    }

    /**
     * 查询服务代码信息(从销管获取)
     * 
     * @param deptNo
     * @param newBsnsType
     * @param channleCode_QD
     * @param empNo
     * @param agentNo
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    @Override
    public Result queryServiceNo(String deptNo, String newBsnsType,
            String channleCode_QD, String empNo, String agentNo)
            throws Exception {
        String url = Config.getProp("SALES_WEBSERVICE_URL");
        String method = Config.getProp("queryServiceNo_METHOD");
        String namespace = Config.getProp("queryServiceNo_NAMESPACE");

        // 拼接请求报文
        String reqXml = "<?xml version=\"1.0\" encoding=\"GBK\"?>" + "<XML>"
                + "<AGENT>" +
                // 归属机构代码(必传)
                "<COMCODE>" + deptNo + "</COMCODE>" +
                // 业务来源(必传)
                "<BUSINESSSOURCE>" + newBsnsType + "</BUSINESSSOURCE>" +
                // 渠道名称(必传)
                "<CHANNELNAME>" + channleCode_QD + "</CHANNELNAME>" +
                // 业务员代码(必传)
                "<USERCODE>" + empNo + "</USERCODE>" +
                // 中介代码(必传)
                "<AGENTCODE>" + agentNo + "</AGENTCODE >" +
                // 服务代码
                "<SERVICENO></SERVICENO>" +
                // 合作机构名称
                "<SERVICENAME></SERVICENAME>" + "</AGENT>" + "</XML>";
        logger.info("查询服务代码信息--》请求报文:" + reqXml);

        String respXml = "";
        try {
            // 调用销管接口
            respXml = WebServiceUtil.call(reqXml, url, method, namespace);
            logger.info("查询服务代码信息--》返回报文:" + respXml);
        } catch (Exception e) {
            logger.info("调用销管接口获取数据异常", e);
            throw new AppException("调用销管接口获取数据异常:", e);
        }

        // 解析响应报文
        Document document = null;
        try {
            document = DocumentHelper.parseText(respXml);
        } catch (DocumentException e) {
            logger.info("解析销管返回报文异常", e);
            throw new AppException("解析销管返回报文异常:", e);
        }
        Element root = document.getRootElement();
        Element RETURN = root.element("RETURN");
        String RETURNCODE = RETURN.elementTextTrim("RETURNCODE");
        Element RETURNMSG = RETURN.element("RETURNMSG");

        // 存放服务代码的List
        List<Map<String, Object>> SERVICENOSList = new ArrayList<Map<String, Object>>();
        if ("0000".equals(RETURNCODE)) {// 成功
            List<Element> SERVICENOS_elementList = RETURNMSG
                    .elements("SERVICENOS");
            for (Element SERVICENOS_element : SERVICENOS_elementList) {
                String SERVICENO = SERVICENOS_element
                        .elementTextTrim("SERVICENO");
                String SERVICENAME = SERVICENOS_element
                        .elementTextTrim("SERVICENAME");

                Map<String, Object> SERVICENOS = new HashMap<String, Object>();
                SERVICENOS.put("SERVICENO", SERVICENO);// 服务代码
                SERVICENOS.put("SERVICENAME", SERVICENAME);// 服务名称

                SERVICENOSList.add(SERVICENOS);
            }
        } else {
            throw new AppException("调用销管接口获取数据失败:RETURNCODE:" + RETURNCODE
                    + "，RETURNMSG:" + RETURNMSG.getTextTrim());
        }
        return Result.success(SERVICENOSList);
    }

    /**
     * 查询中介-协议信息(从销管获取)
     * 
     * @param comCode
     * @param teamCode
     * @param businessSource
     * @param channelName
     * @param prodCode
     * @return
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    @Override
    public Result queryAgentAndAgreeInfo(String comCode, String teamCode,
            String businessSource, String channelName, String prodCode)
            throws Exception {
        String url = Config.getProp("SALES_WEBSERVICE_URL");
        String method = Config.getProp("queryAgentAndAgreeInfo_METHOD");
        String namespace = Config.getProp("queryAgentAndAgreeInfo_NAMESPACE");

        // 拼接请求报文
        String reqXml = "<?xml version=\"1.0\" encoding=\"GBK\"?>" + "<XML>"
                + "<AGENT>" +
                // 归属机构代码(必传)
                "<COMCODE>" + comCode + "</COMCODE>" +
                // 团队代码(必传)
                "<TEAMCODE>" + teamCode + "</TEAMCODE >" +
                // 业务来源(必传)
                "<BUSINESSSOURCE>" + businessSource + "</BUSINESSSOURCE>" +
                // 渠道名称(必传)
                "<CHANNELNAME>" + channelName + "</CHANNELNAME>" +
                // 产品代码(必传)
                "<PRODCODE>" + prodCode + "</PRODCODE>" +
                // 中介代码(校验使用)
                "<AGENTCODE></AGENTCODE>" +
                // 业务员名称
                "<USERCODE></USERCODE>" + "</AGENT>" + "</XML>";
        logger.info("查询中介-协议信息--》请求报文:" + reqXml);

        String respXml = "";
        try {
            // 调用销管接口
            respXml = WebServiceUtil.call(reqXml, url, method, namespace);
            logger.info("查询中介-协议信息--》返回报文:" + respXml);
        } catch (Exception e) {
            logger.info("调用销管接口获取数据异常", e);
            throw new AppException("调用销管接口获取数据异常:", e);
        }

        // 解析响应报文
        Document document = null;
        try {
            document = DocumentHelper.parseText(respXml);
        } catch (DocumentException e) {
            logger.info("解析销管返回报文异常", e);
            throw new AppException("解析销管返回报文异常:", e);
        }
        Element root = document.getRootElement();
        Element RETURN = root.element("RETURN");
        String RETURNCODE = RETURN.elementTextTrim("RETURNCODE");
        Element RETURNMSG = RETURN.element("RETURNMSG");

        // 存放代理、协议信息的List
        List<Map<String, Object>> AGENTAGREEMENTList = new ArrayList<Map<String, Object>>();
        if ("0000".equals(RETURNCODE)) {// 成功
            List<Element> AGENTAGREEMENT_elementList = RETURNMSG
                    .elements("AGENT-AGREEMENT");
            for (Element AGENTAGREEMENT_element : AGENTAGREEMENT_elementList) {
                String AGENTCODE = AGENTAGREEMENT_element
                        .elementTextTrim("AGENTCODE");
                String AGREEMENTNO = AGENTAGREEMENT_element
                        .elementTextTrim("AGREEMENTNO");
                String AGENTNAME = AGENTAGREEMENT_element
                        .elementTextTrim("AGENTNAME");

                Map<String, Object> AGENTAGREEMENT = new HashMap<String, Object>();
                AGENTAGREEMENT.put("AGENTCODE", AGENTCODE);// 代理人代码
                AGENTAGREEMENT.put("AGREEMENTNO", AGREEMENTNO);// 协议代码
                AGENTAGREEMENT.put("AGENTNAME", AGENTNAME);// 代理人名称

                AGENTAGREEMENTList.add(AGENTAGREEMENT);
            }
        } else {
            throw new AppException("调用销管接口获取数据失败:RETURNCODE:" + RETURNCODE
                    + "，RETURNMSG:" + RETURNMSG.getTextTrim());
        }
        return Result.success(AGENTAGREEMENTList);
    }

    @Override
    public FacadePayment saveFacadePayment(CommamtFee commamtFee,GatewayUser gatewayuser) throws Exception {
        FacadePayment payment = new FacadePayment();
        payment.setTransNo(generatePaySerialNumber(commamtFee.getCommamtId()));
        payment.setTransDate(new Date());
        payment.setRequestCode(Config.getProp("life.pay.requestCode"));
        payment.setComCode(gatewayuser.getUserComcode());
        payment.setPayId(commamtFee.getCommamtId());
        payment.setTransAmt(DecimalUtil.round(commamtFee.getTotPremAMt(), 2));
        payment.setInsertDate(new Date());
        payment.setStatus("1");
        payment.setPayName("出库单号_" + commamtFee.getCommamtId());
        payment.setRemark("激活卡出库");
        payment.setFkChannelCode("");
        payment.setUserCode(gatewayuser.getUserCode());
        outboundCardApplyDao.saveFacadePayment(payment);
        return payment;
    }
    /**
     * 根据暂存单号生成支付流水号
     * @param stagNo
     * @return
     */
    private String generatePaySerialNumber(String stagNo) throws Exception {
        String code = outboundCardApplyDao.findFacadePaymentBystagNo(stagNo);
        if (code == null || code.equals("")) {
            code = "0001";
        }
        return stagNo + "PAY" + code;
    }
    @Override
    public FacadePayment getFacadePaymentByTransNo(String transNo) throws Exception{
        return outboundCardApplyDao.getFacadePaymentByTransNo(transNo);
    }
    @Override
    public boolean updateFacadePayMent(FacadePayment payment) throws Exception{
        return outboundCardApplyDao.updateFacadePayment(payment);
    }
    @Override
    public FacadePayment queryPayment(HashMap<String,String> map) throws Exception{
        return outboundCardApplyDao.queryPayment(map);
    }
}
